import { FIMouse } from "./FIMouse.js";
import { FIScene } from "./FIScene.js";
export class FIEngine {
  protected _scene = new FIScene();
  protected _canvas = document.createElement('canvas');
  protected _ctx = this._canvas.getContext('2d')!;
  protected _container: HTMLElement;
  private _mouseX: any;
  private _mouseY: any;

  get scene() { return this._scene; }
  set scene(v) { this._scene = v; }
  get canvas() { return this._canvas; }
  get ctx() { return this._ctx; }
  get container(): HTMLElement { return this._container; }

  constructor(container: HTMLElement) {
    this._container = container;


    this._canvas.style.position = 'absolute';
    this._canvas.style.left = '0px';
    this._canvas.style.right = '0px';
    this._canvas.style.top = '0px';
    this._canvas.style.bottom = '0px';
    this._canvas.addEventListener('contextmenu', e => { e.preventDefault() })
    container.append(this._canvas);

    this.resize();
    this.init();
  }
  init(): FIEngine {
    window.addEventListener('resize', this.resize);
    this.createMouse().onMouseMove = ({ x, y }) => {
      this._mouseX = x;
      this._mouseY = y;
    }
    return this;
  }
  destory(): FIEngine {
    window.removeEventListener('resize', this.resize);
    return this;
  }
  resize = (): FIEngine => {
    const { width, height } = this.container.getBoundingClientRect();
    this.canvas.width = width;
    this.canvas.height = height;
    return this;
  }
  render(): FIEngine {
    const { width, height } = this._canvas;
    this._ctx.clearRect(0, 0, width, height);
    this._ctx.save()
    this._scene.render(this._ctx);
    this._ctx.restore()

    const mx = 0.5 + Math.floor(this._mouseX);
    const my = 0.5 + Math.floor(this._mouseY);
    this._ctx.beginPath();
    this._ctx.moveTo(mx + 8, my + 20)
    this._ctx.lineTo(mx, my)
    this._ctx.lineTo(mx + 20, my + 8)
    this._ctx.lineTo(mx + 10, my + 10)
    this._ctx.closePath();
    this._ctx.fillStyle = 'white'
    this._ctx.fill()
    this._ctx.strokeStyle = 'black'
    this._ctx.stroke()
    return this;
  }

  private _prevTime?: number;
  loop: FrameRequestCallback = (time: DOMHighResTimeStamp) => {
    if (time && this._prevTime) {
      this._scene.update(time - this._prevTime)
      this._prevTime = time;
    }
    this._prevTime = time;
    this.render()
    requestAnimationFrame(this.loop)
  }
  createMouse(): FIMouse {
    return new FIMouse(this);
  }
  getImg(path: string): CanvasImageSource {
    const img = document.createElement('img');
    img.src = path;
    return img
  }
}